//
//  ZNEmotionManager.swift
//  ZNWeibo
//
//  Created by FunctionMaker on 2017/9/7.
//  Copyright © 2017年 FunctionMaker. All rights reserved.
//

import UIKit

class ZNEmotionManager {
    /// 表情管理单例
    static let shared = ZNEmotionManager()
    
    /// 表情包数组
    lazy var emoticonPackages = [ZNEmoticonPackage]()
    
    // 外界禁用构造器，只能访问单例对象
    // OC 要重写 allocWithZone 方法
    private init() {
        loadPackage()
    }
}

extension ZNEmotionManager {
    
    func emoticonString(withString: String, font: UIFont) -> NSAttributedString {
        let resultString = NSMutableAttributedString(string: withString)
        
        // 1. 建立正则表达式，提取所有的表情文字
        // [], () 都是正则表达式的保留字符，如果参与匹配，需要转义
        
        let pattern = "\\[.*?\\]"
        
        // 2. 建立正则表达式
        guard let regx = try? NSRegularExpression(pattern: pattern, options: [])  else {
            return resultString
        }
        
        // 3. 匹配所有项
        let matches = regx.matches(in: withString, options: [], range: NSRange(location: 0, length: resultString.length))
        
        // 4. 遍历所有匹配结果
        // 反序遍历，防止在替换前面的字符时导致后面的字符位置变化
        for match in matches.reversed() {
            let range = match.range
            
            let subString = (resultString.string as NSString).substring(with: range)
            
            // 5. 将表情文字替换为图片
            if let emoticon = ZNEmotionManager.shared.findEmoticon(withString: subString) {
                resultString.replaceCharacters(in: range, with: emoticon.imageText(font: font))
            }
            
        }
        
        // 6. 统一设置字符串的字体
        resultString.addAttributes([NSFontAttributeName: font], range:         NSRange(location: 0, length: resultString.length))
        
        return resultString
    }
    
    /// 通过表情字符串查找对应的图片
    ///
    /// - Parameter withString: 表情字符串
    /// - Returns: 查找图片结果
    fileprivate func findEmoticon(withString: String) -> ZNEmoticon? {
        
        for package in emoticonPackages {
//            let result = package.emoticons.filter({ (emoticon) -> Bool in
//                return emoticon.chs == withString
//            })
            
            // 如果闭包中只有一句且是返回代码，闭包定义格式可以省略，使用$0、$1...表示参数
            // 效率较低，因为图片和字符串是一一对应的。
//            let result = package.emoticons.filter { $0.chs == withString
//            }
            
            for emoticon in package.emoticons {
                if emoticon.chs == withString {
                    
                    return emoticon
                }
            }
        }
        
        return nil
    }
}

private extension ZNEmotionManager {
    func loadPackage() {
        guard let plistPath = Bundle.main.emoticonsBundle.path(forResource: "emoticons.plist", ofType: nil),
              let emoticonInfo = NSArray(contentsOfFile: plistPath) as? [[String: String]],
              let emotiPackages = NSArray.yy_modelArray(with: ZNEmoticonPackage.self, json: emoticonInfo) as? [ZNEmoticonPackage]
        else {
            return
        }
        
        // 设置表情包数据
        emoticonPackages += emotiPackages
    }
}
